package main

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"github.com/tidwall/gjson"
	"io/ioutil"
	"iot-base/common/cache"
	"iot-base/common/ctrltype"
	"iot-base/common/logger"
	"iot-base/common/notify"
	"net/http"
	"os"
	"time"
)

const (
	NVFBrand = "NewVersionFaceBrand"
	httpPort = "9050"
	wsPort   = "9501"
)

type NewVersionClient struct {
	DoorControl
}

//此处为新视人脸控制器的发送结构
type newVersionSend struct {
	ID     int         `json:"id"`
	Method string      `json:"method"`
	Params interface{} `json:"params,omitempty"`
}

type newVersionPersonAdd struct {
	Type     int    `json:"Type"` //人员类型 1.内部员工 2.访客 3.黑名单
	Code     string `json:"Code"`
	Name     string `json:"Name"`
	Sex      string `json:"Sex"`
	Birthday string `json:"Birthday"`

	GuestInfo *guestInfo `json:"GuestInfo,omitempty"`

	URL     []string `json:"URL,omitempty"`
	Feature []string `json:"Features,omitempty"`
	Images  []string `json:"Images,omitempty"`

	Cards *[]NewVersionPersonCard `json:"Cards,omitempty"`
}

type guestInfo struct {
	Corp       string       `json:"Corp"`
	Phone      string       `json:"Phone"`
	CarLicense string       `json:"CarLicense"`
	Partner    string       `json:"Partner"`
	Host       string       `json:"Host"`
	AccessTime []AccessTime `json:"AccessTime"`
}

type AccessTime struct {
	From int64 `json:"from"`
	To   int64 `json:"to"`
}

type NewVersionPersonDel struct {
	Code string `json:"Code"`
}

type NewVersionPersonQuery struct {
	Condition PersonQueryCondition `json:"Condition"`
}

type PersonQueryCondition struct {
	Type     int    `json:"Type,omitempty"`
	CodeLike string `json:"CodeLike,omitempty"`
	NameLike string `json:"NameLike,omitempty"`
	Limit    int    `json:"Limit"`
	Offset   int    `json:"Offset"`
}

type NewVersionOpen struct {
	Channel int `json:"channel"`
}

type NewVersionPersonCard struct {
	ID string `json:"ID"`
	//卡号
	Type int `json:"Type"`
	//卡类型
	Validity []string `json:"Validity"`
	//有效日期,起始 终止2个
	ValidityTime []string `json:"ValidityTime,omitempty"`
	//有效时间,起始 终止2个
	Memo Memo `json:"Memo"`
}

type Memo struct {
	Entrance string `json:"Entrance"`
	//地址
}

type NewVersionCardAdd struct {
	ID   string `json:"ID"`
	Card Card   `json:"Card"`
}

type Card struct {
	PersonCode string   `json:"PersonCode"`
	Type       int      `json:"Type"`
	Validity   []string `json:"Validity"`
	Memo       Memo     `json:"Memo"`
}

type newVersionCardQuery struct {
	Condition cardQueryCondition `json:"Condition"`
}

type cardQueryCondition struct {
	ID         string `json:"ID,omitempty"`
	PersonCode string `json:"PersonCode,omitempty"`
	Offset     int    `json:"Offset"`
	Limit      int    `json:"Limit"`
}

type newVersionCardDel struct {
	ID string `json:"ID"`
}

//type NewVersionParams struct {
//	PersonAdd   *[]NewVersionPersonAdd `json:"personAdd,omitempty"`
//	PersonDel   *[]NewVersionPersonDel `json:"personDel,omitempty"`
//	PersonQuery *NewVersionPersonQuery `json:"personQuery,omitempty"`
//
//	CardAdd   *NewVersionCardAdd   `json:"cardAdd,omitempty"`
//	CardDel   *NewVersionCardDel   `json:"cardDel,omitempty"`
//	CardQuery *NewVersionCardQuery `json:"cardQuery,omitempty"`
//
//	Open *NewVersionOpen `json:"open,omitempty"`
//}

func (d *NewVersionClient) Order(pCmd *ctrltype.CtrlCmd) (map[string]interface{}, error) {
	switch pCmd.ID {
	case addPerson:
		return d.insertPerson(pCmd.ThingID, pCmd.Params, pCmd.ArrayParams)
	case delPerson:
		return d.delPerson(pCmd.ThingID, pCmd.Params, pCmd.ArrayParams)
	case queryPerson:
		return d.queryPerson(pCmd.ThingID, pCmd.Params, pCmd.ArrayParams)
	case addCard:
		return d.insertCard(pCmd.ThingID, pCmd.Params, pCmd.ArrayParams)
	case delCard:
		return d.delCard(pCmd.ThingID, pCmd.Params, pCmd.ArrayParams)
	case queryCard:
		return d.queryCard(pCmd.ThingID, pCmd.Params, pCmd.ArrayParams)
	case openDoor:
		return d.open(pCmd.ThingID, pCmd.Params, pCmd.ArrayParams)
	case getNoImagePerson:
		return d.getNoImage(pCmd.ThingID, pCmd.Params, pCmd.ArrayParams)
	default:
		return nil, errors.New("no this order")
	}
}

type newVersionPersonAddIn struct {
	Person *newVersionPersonAdd `json:"Person"`
}

func (d *NewVersionClient) insertPerson(id string, params map[string]interface{}, arrayParams []map[string]interface{}) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	persons := make([]newVersionPersonAddIn, len(arrayParams))
	fmt.Println("arrayParams:", arrayParams)
	for n, v := range arrayParams {
		Type := v["type"].(int8)
		Code := v["code"].(string)
		Name := v["name"].(string)
		Sex := v["sex"].(string)
		Birthday := v["birthday"].(string)
		persons[n] = newVersionPersonAddIn{
			Person: &newVersionPersonAdd{
				Type:     int(Type),
				Code:     Code,
				Name:     Name,
				Sex:      Sex,
				Birthday: Birthday,
			},
		}
		AccesstimeFrom, ok1 := v["accesstimefrom"]
		AccesstimeTo, ok2 := v["accessstimeto"]
		if Type == 2 && ok1 != false && ok2 != false {
			AccesstimeF, err := typeOfInt64(AccesstimeFrom)
			if err != nil {
				return nil, err
			}
			AccesstimeT, err := typeOfInt64(AccesstimeTo)
			if err != nil {
				return nil, err
			}
			persons[n].Person.GuestInfo = &guestInfo{
				Host: Name,
				AccessTime: []AccessTime{{
					From: AccesstimeF,
					To:   AccesstimeT,
				}},
			}
		}
		url, okurl := v["url"].(string)
		if okurl && url != "" {
			persons[n].Person.URL = []string{url}
		}
		feature, okfeature := v["feature"].(string)
		if okfeature && feature != "" {
			persons[n].Person.Feature = []string{feature}
		}
		image, okimage := v["image"].(string)
		if okimage && image != "" {
			img := image
			f, err := os.Stat(img)
			if err != nil {
				fmt.Println(err)
			}
			if (float64(f.Size()) / 1024) > 2048 {
				fmt.Println("图片大小不能超过2M")
				return nil, errors.New("图片大小不能超过2M")
			}
			// 读取文件
			b, err := ioutil.ReadFile(img)
			if err != nil {
				return nil, err
			}
			//os.Remove(img)
			// 转成 base64
			encodeString := base64.StdEncoding.EncodeToString(b)
			persons[n].Person.Images = []string{encodeString}
		}
	}
	if persons != nil {
		addpersion := newVersionSend{
			ID:     1,
			Method: "personnelData.savePersons",
			Params: persons,
		}
		msg, err := json.Marshal(addpersion)
		if err != nil {
			return nil, err
		}
		client := NewVersionMap[NVFBrand].Clients[id]
		if client == nil {
			return nil, errors.New("get client is nil")
		}
		client.Send(msg)
		res, err := client.Read()
		if err != nil {
			return nil, err
		}
		reStr := string(res)
		if gjson.Get(reStr, "id").Int() != 1 {
			return nil, errors.New("seq not sync")
		}
		if !gjson.Get(reStr, "result").Bool() {
			return nil, errors.New("order is fail")
		}
		params := gjson.Get(reStr, "params").Array()
		for _, v := range params {
			result[v.Get("Code").String()] = v.Get("Result").Bool()
			if !v.Get("Result").Bool() {
				result["errcode"] = v.Get("ErrorCode").Int()
				result["msg"] = v.Get("ErrorMessage").String()
			}
		}
		return result, nil
	}
	return nil, errors.New("personAdd is nil")
}

func (d *NewVersionClient) delPerson(id string, params map[string]interface{}, arrayParams []map[string]interface{}) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	delparams := make([]NewVersionPersonDel, 0)
	fmt.Println("params:", params)
	for _, v := range params {
		delparams = append(delparams, NewVersionPersonDel{fmt.Sprint(v.(int64))})
	}
	delpersion := newVersionSend{
		ID:     2,
		Method: "personnelData.removePersons",
		Params: delparams,
	}
	msg, err := json.Marshal(delpersion)
	fmt.Println("send:", string(msg))
	if err != nil {
		return nil, err
	}
	client := NewVersionMap[NVFBrand].Clients[id]
	if client == nil {
		return nil, errors.New("get client is nil")
	}
	client.Send(msg)
	fmt.Println("send:", string(msg))
	res, err := client.Read()
	if err != nil {
		return nil, err
	}
	reStr := string(res)
	fmt.Println("restr:", reStr)
	if gjson.Get(reStr, "id").Int() != 2 {
		return nil, errors.New("seq not sync")
	}
	if !gjson.Get(reStr, "result").Bool() {
		return nil, errors.New("order is fail")
	}
	param := gjson.Get(reStr, "params").Array()
	for _, v := range param {
		result[v.Get("Code").String()] = v.Get("Result").Bool()
	}
	return result, nil
}

func (d *NewVersionClient) queryPerson(id string, params map[string]interface{}, arrayParams []map[string]interface{}) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	limit := params["limit"].(int8)
	offset := params["offset"].(int8)
	personparam := NewVersionPersonQuery{
		PersonQueryCondition{
			Limit:  int(limit),
			Offset: int(offset),
		},
	}
	Type, typeok := params["type"]
	if typeok {
		personparam.Condition.Type = int(Type.(int8))
	}
	codelike, codeok := params["codelike"]
	if codeok {
		personparam.Condition.CodeLike = codelike.(string)
	}
	namelike, nameok := params["namelike"]
	if nameok {
		personparam.Condition.NameLike = namelike.(string)
	}
	querypersion := newVersionSend{
		ID:     3,
		Method: "personManager.getPersons",
		Params: personparam,
	}
	msg, err := json.Marshal(querypersion)
	if err != nil {
		return nil, err
	}
	client := NewVersionMap[NVFBrand].Clients[id]
	if client == nil {
		return nil, errors.New("get client is nil")
	}
	client.Send(msg)
	res, err := client.Read()
	if err != nil {
		return nil, err
	}
	reStr := string(res)
	if gjson.Get(reStr, "id").Int() != 3 {
		return nil, errors.New("seq not sync")
	}
	if !gjson.Get(reStr, "result").Bool() {
		return nil, errors.New("order is fail")
	}
	param := gjson.Get(reStr, "params.Persons").Array()
	for _, v := range param {
		result[v.Get("Code").String()] = v.Raw
	}
	return result, nil
}

func (d *NewVersionClient) insertCard(id string, params map[string]interface{}, arrayParams []map[string]interface{}) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	ID := params["id"].(string)
	code := params["code"].(string)
	Type := params["type"].(int8)

	cardparam := NewVersionCardAdd{
		ID: ID,
		Card: Card{
			PersonCode: code,
			Type:       int(Type),
		},
	}
	from, fromok := params["from"]
	if fromok {
		cardparam.Card.Validity[0] = from.(string)
	}
	to, took := params["to"]
	if took {
		cardparam.Card.Validity[1] = to.(string)
	}
	insertcard := newVersionSend{
		ID:     4,
		Method: "cardManager.updateCard",
		Params: cardparam,
	}
	msg, err := json.Marshal(insertcard)
	if err != nil {
		return nil, err
	}
	client := NewVersionMap[NVFBrand].Clients[id]
	if client == nil {
		return nil, errors.New("get client is nil")
	}
	client.Send(msg)
	res, err := client.Read()
	if err != nil {
		return nil, err
	}
	reStr := string(res)
	if gjson.Get(reStr, "id").Int() != 4 {
		return nil, errors.New("seq not sync")
	}
	if !gjson.Get(reStr, "result").Bool() {
		return nil, errors.New("order is fail")
	}
	param := gjson.Get(reStr, "result").Bool()
	result["result"] = param
	return result, nil
}

func (d *NewVersionClient) delCard(id string, params map[string]interface{}, arrayParams []map[string]interface{}) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	ID := params["id"].(string)
	cardparams := newVersionCardDel{
		ID: ID,
	}
	delCard := newVersionSend{
		ID:     5,
		Method: "cardManager.removeCard",
		Params: cardparams,
	}
	msg, err := json.Marshal(delCard)
	if err != nil {
		return nil, err
	}
	client := NewVersionMap[NVFBrand].Clients[id]
	if client == nil {
		return nil, errors.New("get client is nil")
	}
	client.Send(msg)
	res, err := client.Read()
	if err != nil {
		return nil, err
	}
	reStr := string(res)
	if gjson.Get(reStr, "id").Int() != 5 {
		return nil, errors.New("seq not sync")
	}
	if !gjson.Get(reStr, "result").Bool() {
		return nil, errors.New("order is fail")
	}
	result["result"] = gjson.Get(reStr, "result").Bool()
	return result, nil
}

func (d *NewVersionClient) queryCard(id string, params map[string]interface{}, arrayParams []map[string]interface{}) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	cardparams := newVersionCardQuery{cardQueryCondition{}}
	personcode, ok1 := params["personcode"]
	if ok1 {
		cardparams.Condition.PersonCode = personcode.(string)
	}
	ID, ok2 := params["id"]
	if ok2 {
		cardparams.Condition.ID = ID.(string)
	}
	offset := params["offset"].(int8)
	cardparams.Condition.Offset = int(offset)
	limit := params["limit"].(int8)
	cardparams.Condition.Limit = int(limit)
	queryCard := newVersionSend{
		ID:     6,
		Method: "cardManager.getCards",
		Params: cardparams,
	}
	msg, err := json.Marshal(queryCard)
	fmt.Println("send:", string(msg))
	if err != nil {
		return nil, err
	}
	client := NewVersionMap[NVFBrand].Clients[id]
	if client == nil {
		return nil, errors.New("get client is nil")
	}
	client.Send(msg)
	res, err := client.Read()
	if err != nil {
		return nil, err
	}
	reStr := string(res)
	fmt.Println("restr:", reStr)
	cards := gjson.Get(reStr, "params.Cards").Array()
	if gjson.Get(reStr, "id").Int() != 6 {
		return nil, errors.New("seq not sync")
	}
	if !gjson.Get(reStr, "result").Bool() {
		return nil, errors.New("order is fail")
	}
	for _, v := range cards {
		codeid := v.Get("ID").String()
		//personcode :=  v.Get("result").Bool()
		//Type := v.Get("Type").Int()
		//from := v.Get("Validity").Array()[0].String()
		//to := v.Get("Validity").Array()[1].String()
		result[codeid] = v.Raw
	}
	return result, nil
}

func (d *NewVersionClient) open(id string, params map[string]interface{}, arrayParams []map[string]interface{}) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	open := newVersionSend{
		ID:     7,
		Method: "devDoor.openOnce",
		Params: NewVersionOpen{
			0,
		},
	}
	msg, err := json.Marshal(open)
	if err != nil {
		return nil, err
	}
	client := NewVersionMap[NVFBrand].Clients[id]
	if client == nil {
		return nil, errors.New("get client is nil")
	}
	client.Send(msg)
	res, err := client.Read()
	if err != nil {
		return nil, err
	}
	reStr := string(res)
	if gjson.Get(reStr, "id").Int() != 7 {
		return nil, errors.New("seq not sync")
	}
	if !gjson.Get(reStr, "result").Bool() {
		return nil, errors.New("order is fail")
	}
	result["result"] = gjson.Get(reStr, "result").Bool()
	return result, nil
}

func (d *NewVersionClient) getNoImage(id string, params map[string]interface{}, arrayParams []map[string]interface{}) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	send := newVersionSend{
		ID:     8,
		Method: "personManager.getNoImagePersonCodes",
		Params: NewVersionOpen{
			0,
		},
	}
	msg, err := json.Marshal(send)
	if err != nil {
		return nil, err
	}
	client := NewVersionMap[NVFBrand].Clients[id]
	if client == nil {
		return nil, errors.New("get client is nil")
	}
	client.Send(msg)
	res, err := client.Read()
	if err != nil {
		return nil, err
	}
	reStr := string(res)
	if gjson.Get(reStr, "id").Int() != 7 {
		return nil, errors.New("seq not sync")
	}
	if !gjson.Get(reStr, "result").Bool() {
		return nil, errors.New("order is fail")
	}
	result["result"] = gjson.Get(reStr, "result").Bool()
	result["list"] = gjson.Get(reStr, "params.Codes")
	return result, nil
}

//这里使用的当前所有需要的服务用于上报
var NewVersionFaceSvMap = map[string]func(){
	"http": NewVersionFaceHttpRegister,
	"ws":   NewVersionFaceWsRegister,
}

var (
	NewVersionFaceWebSocketHub *WebsocketHub
	NewVersionMap              map[string]NewVersionSv
)

func NewVersionFaceRegister(id, brand string) {
	if _, ok := NewVersionMap[brand]; !ok {
		NewVersionMap[brand] = NewVersionSv{
			ID:      id,
			Sv:      make(map[string]NewVersionSvStatus),
			Clients: make(map[string]Client),
		}
		for k, v := range NewVersionFaceSvMap {
			ctx, cancel := context.WithCancel(context.Background())
			NewVersionMap[brand].Sv[k] = NewVersionSvStatus{
				Ctx:    ctx,
				Cancel: cancel,
				Status: true,
			}
			go v()
		}
	} else {
		for k, v := range NewVersionFaceSvMap {
			ctx, cancel := context.WithCancel(context.Background())
			if !NewVersionMap[brand].Sv[k].Status {
				NewVersionMap[brand].Sv[k] = NewVersionSvStatus{
					Ctx:    ctx,
					Cancel: cancel,
					Status: true,
				}
				go v()
			}
		}
	}
}

func NewVersionUnRegister(id string) {
	if k, ok := NewVersionMap[NVFBrand].Sv[id]; ok {
		k.Cancel()
		k.Status = false
	}
}

type NewVersionSv struct {
	ID      string //用于上报的物模型关联设备id
	Sv      map[string]NewVersionSvStatus
	Clients map[string]Client
}

type NewVersionSvStatus struct {
	Ctx    context.Context
	Cancel func()
	Status bool
}

func NewVersionFaceWsRegister() {
	ctx, cancel := context.WithCancel(context.Background())
	if v, ok := NewVersionMap[NVFBrand]; ok {
		if sv, ok := v.Sv["ws"]; ok {
			sv.Ctx = ctx
			sv.Cancel = cancel
		}
	}
	defer func() {
		if v, ok := NewVersionMap[NVFBrand]; ok {
			if sv, ok := v.Sv["ws"]; ok {
				sv.Status = false
			}
		}
	}()
	NewVersionFaceWebSocketHub = NewWebsocketHub()
	r := gin.Default()
	r.GET("/ws", NewVersionFaceWs)
	fmt.Println(r.Run(":" + wsPort))
}

func NewVersionFaceWs(c *gin.Context) {
	conn, err := (&websocket.Upgrader{
		CheckOrigin:     func(r *http.Request) bool { return true },
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
	}).Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		http.NotFound(c.Writer, c.Request)
		return
	}
	sn, is := c.GetQuery("SerialNo")
	if !is {
		return
	}
	thingInfo, err := cache.GetThingByBid(sn)
	if thingInfo == nil || err != nil {
		conn.Close()
		return
	}
	if _, ok := NewVersionFaceWebSocketHub.Clients[sn]; ok {
		return
	}
	config := Config{
		ID:            thingInfo.Thing.UID,
		Brand:         NVFBrand,
		Type:          "websocket",
		WebsocketConn: conn,
	}
	client := NewClient(config)
	NewVersionMap[NVFBrand].Clients[sn] = client
	go client.Start()
	// 设置关闭处理器
}

func NewVersionFaceHttpRegister() {
	ctx, cancel := context.WithCancel(context.Background())
	if v, ok := NewVersionMap[NVFBrand]; ok {
		if sv, ok := v.Sv["http"]; ok {
			sv.Ctx = ctx
			sv.Cancel = cancel
		}
	}
	defer func() {
		if v, ok := NewVersionMap[NVFBrand]; ok {
			if sv, ok := v.Sv["http"]; ok {
				sv.Status = false
			}
		}
	}()
	r := gin.Default()
	r.GET("/api/rpc", NewVersionFaceHttpServer)
	r.POST("/api/picture", NewVersionFaceHttpPicture)
	fmt.Println(r.Run(":" + httpPort))
}

func NewVersionFaceHttpServer(c *gin.Context) {
	serialNo := c.Query("SerialNo")
	for key, value := range NewVersionMap[NVFBrand].Clients {
		if key == serialNo {
			id := value.GetID()
			notify.RawData(id, "status", "", 0, "1", time.Now().Unix(), time.Now().Unix())
		}
	}
}

func NewVersionFaceHttpPicture(c *gin.Context) {
	//SerialNo := c.Query("SerialNo")
	logger.Log.Info("in report")
	now := time.Now().Unix()
	err := c.Request.ParseMultipartForm(128)
	if err != nil {
		fmt.Println("multi err:", err)
	}
	//fmt.Println("r.postForm:  ",c.Request.PostForm)
	readBuffer := c.Request.PostForm
	JsonMsg := readBuffer["json"]
	events := gjson.Get(JsonMsg[0], "Events").Array()
	if len(events) == 0 {
		fmt.Println("no event!")
	}
	fmt.Println("JsonMsg:", JsonMsg)
	logger.Log.Info(fmt.Sprint(Register))
	id := NewVersionMap[NVFBrand].ID
	fmt.Println("events:", events)
	for _, event := range events {
		params := map[string]interface{}{}
		PassResult := gjson.Get(event.String(), "AccessInfo.PassResult").Int()
		if event.Get("Code").String() != "EventFaceRecognizeCutout" {
			continue
		}
		result := "未动作"
		msg := NewVersionFaceEventMsg[int(PassResult)]
		switch PassResult {
		case 1, 17:
			result = "开"
			notify.RawData(id, "rtstate", "", 0, 1, now, now)
		}
		notify.RawData(id, "rtstate", "", 0, 3, now, now)
		notify.RawData(id, "status", "", 0, msg, now, now)
		params["result"] = result
		params["Mod"] = result
		params["Name"] = event.Get("RecognizeResults").Array()[0].Get("PersonInfo.Name").String()
		params["Now"] = now
		params["Event"] = msg
		notify.RawEvent(id, "guardLog", time.Now(), params, nil)
		logger.Log.Info("get event:" + fmt.Sprint(params) + " id:" + id)
	}
	logger.Log.Info("out report")
}

var NewVersionFaceEventMsg map[int]string

func init() {
	NewVersionFaceEventMsg = map[int]string{
		0:  "通行结果未知错误",
		1:  "通行成功",
		2:  "通行失败.访客访问时间不符",
		3:  "通行失败,未设置权限组",
		4:  "通行失败,未配置时段",
		5:  "通行失败,不在通行时间段内",
		6:  "需等待刷脸",
		7:  "需等待刷卡",
		8:  "通行失败,超时",
		9:  "通行失败,黑名单",
		10: "通行失败,无效卡",
		11: "通行失败,通行时段设置错误",
		12: "通行失败,触发器类型错误",
		13: "通行失败,无信息",
		14: "通行失败,门处于常开状态",
		15: "通行失败,门处于常闭状态",
		16: "通行失败,陌生人",
		17: "通行成功,已佩戴安全帽",
		18: "通行失败,未佩戴安全帽",
		19: "通行失败,刷卡信息不匹配",
		20: "通行失败,体温检测异常",
		21: "已佩戴口罩",
		22: "未佩戴口罩",
		23: "通行失败,检测健康码失败",
		24: "校验卡成功",
		25: "校验卡失败",
		26: "通行保护,需指定刷卡id",
		27: "通行失败,卡id黑名单",
		28: "通行失败,需先刷卡",
		29: "通行失败,未连接平台",
	}
}
